/******************************************************************************
 * @file bsp_led_handler.h
 *
 * @par dependencies
 *  - stdint.h
 *
 * @brief bsp handler for LED control
 *
 * Processing flow:
 *
 * call directly.
 *
 * @author iceiceiceberg
 *
 * @date 2025-05-11
 *
 * @version V1.0.0
 *
 * @note 1 tab == 4 spaces
 *
 *****************************************************************************/
#ifndef __BSP_LED_HANDLER_H__
#define __BSP_LED_HANDLER_H__

//********************************* Includes ********************************//
#include <stdint.h>
#include <stdio.h>

#include "bsp_led_driver.h"

//********************************* Includes ********************************//

//********************************* Defines *********************************//
typedef struct bsp_led_handler bsp_led_handler_t;

typedef enum
{
    LED1                      = 0,      
    LED2,                                
    LED3,                                
    LED4,                                 
    LED5,
    LED6,
    LED7,
    LED8,
    LED9,
    LED10,                                 
    MAX_LED_TARGETS_NUM,
    LED_NOT_INISTED = 0xFF                        
} index_led_instance_t;

typedef enum
{
    LED_HANDLER_IS_NOT_INSTED = 0,              /* Not instantiated          */
    LED_HANDLER_IS_INSTED     = 1               /* Instantiated              */
} handler_init_state_t;

typedef enum
{
    HANDLER_OK                = 0,              /* No error                  */
    HANDLER_ERROR             = 1,              /* General error             */
    HANDLER_ERROR_RESOURCE    = 2,              /* Error resource            */
    HANDLER_ERROR_TIMEOUT     = 3,              /* Timeout error             */
    HANDLER_ERROR_PARAM       = 4,              /* Parameter error           */
    HANDLER_ERROR_MEMORY      = 5,              /* Memory allocation error   */
    HANDLER_RESERVED          = 0xFF            /* Reserved                  */
} handler_state_t;

typedef handler_state_t ( *pf_handler_led_control ) (
                                bsp_led_handler_t   * const       p_self, 
                                uint32_t ,          //   Period in milliseconds
                                uint32_t ,          //   blink repetition times
                                blink_proportion_t, //               on and off
                                index_led_instance_t//Index of the LED instance
                                );                  /* LED control function  */

typedef handler_state_t ( *pf_handler_led_register ) (
                                bsp_led_handler_t    * const       p_self, 
                                bsp_led_driver_t     * const p_led_driver,
                                index_led_instance_t * const        index
                                );

typedef struct 
{
    bsp_led_driver_t * array_led_driver[MAX_LED_TARGETS_NUM];
                                                /* Array of pointers to LED  */
    index_led_instance_t                               index;
} handler_led_instance_t;

#ifdef OS_SUPPORT
typedef struct 
{
    handler_state_t ( *pf_handler_os_critical_enter ) ( void );
                                               /* OS critical enter function */ 
                                                
    handler_state_t ( *pf_handler_os_critical_exit )  ( void );
                                               /* OS critical exit function  */
} handler_os_critical_t;

typedef struct 
{
    handler_state_t ( *pf_os_thread_create )  (
                                          void *           p_task_function,
							        const char *   const            p_name,		
							        const uint16_t            usStackDepth,
							              void *   const   p_thread_params,
							              uint32_t         thread_priority,
							              void **  const p_thread_handler );
                                               /* OS thread create function  */

    handler_state_t ( *pf_os_thread_delete )  (
                                          void *   const p_thread_handler );
                                               /* OS thread delete function  */
} handler_os_thread_t;

typedef struct 
{
    handler_state_t ( *pf_os_queue_create )  (
                                          uint32_t const      iterm_num,
                                          uint32_t const     iterm_size,
                                          void **  const p_queue_handle);
                                                /* OS queue create function  */

    handler_state_t ( *pf_os_queue_put )     (
                                          void *   const  p_queue_handle,
                                          void *   const          p_item,
                                          uint32_t const         timeout);
                                                /* OS queue put function     */

    handler_state_t ( *pf_os_queue_get )     (
                                          void *   const  p_queue_handle,
                                          void *   const             msg,
                                          uint32_t const         timeout);
                                                /* OS queue get function     */

    handler_state_t ( *pf_os_queue_delete )  (
                                          void *   const  p_queue_handle);
                                                /* OS queue delete function  */
} handler_os_queue_t;

typedef struct 
{
    handler_state_t (*pf_handler_os_delay) (uint32_t const); 
                                                /* OS delay  function        */
} handler_os_delay_t;
#endif // OS_SUPPORT

typedef struct 
{
    handler_state_t (*pf_handler_get_core_base_time) (uint32_t * const); 
                                                /* Get core base time        */
} handler_core_base_time_ms_t;

typedef struct bsp_led_handler
{
    /************* Internal runtime data for internal status *****************/
    /* Handler instance flag                             */
    uint8_t                                is_instantiated; 

    /* Registered driver targets                         */
    handler_led_instance_t                    led_instance;

    /* Pointer to the queue handle                       */
    void                                   *p_queue_handle; 
    /* Pointer to the thread handle                      */ 
    void                                  *p_thread_handle;

    /************* Interface for internal use ********************************/
    /************* Interface from core *******************/
    /* System timebase interface                         */
    handler_core_base_time_ms_t           *p_sys_time_base;

    /************* Interface from os *********************/
#ifdef OS_SUPPORT
    /* OS delay pointer                                  */
    handler_os_delay_t                         *p_os_delay;

    /* OS queue pointer                                  */
    handler_os_queue_t                         *p_os_queue;

    /* OS thread pointer                                 */
    handler_os_thread_t                       *p_os_thread;

    /* OS critical section handler                       */
    handler_os_critical_t                   *p_os_critical;
#endif // OS_SUPPORT

    /************* APIs for external use *************************************/
    /* APIs for os layer                                 */
    /* LED control                                       */
    pf_handler_led_control                pf_led_controler;

    /* APIs for internal driver                          */
    /* Register LED operations                           */
    pf_handler_led_register                pf_led_register;          
} bsp_led_handler_t;

//********************************* Defines *********************************//

//********************************* Declaring *******************************//
/**
 * @brief Instantiates the bsp_led_handler_t target.
 * 
 * Steps:
 * 1. Check input parameters
 * 2. Check if resource is already instantiated
 * 3. Mount external interfaces
 * 4. Initialize LED instance
 * 5. Set instantiation flag
 *  
 * @param[in] self        : Pointer to the target of driver.
 * @param[in] sys_time    : Pointer to the core_base_time_ms_t interface.
 * @param[in] os_delay    : Pointer to the os_delay_interface.
 * @param[in] os_queue    : Pointer to the OS queue interface.
 * @param[in] os_critical : Pointer to the OS critical section interface.
 * @return handler_state_t : Status of the function.
 * 
 * */
handler_state_t bsp_led_handler_inst(
                          bsp_led_handler_t           * const             self,
                          handler_core_base_time_ms_t * const         sys_time,
#ifdef OS_SUPPORT
                          handler_os_delay_t          * const         os_delay,
                          handler_os_queue_t          * const         os_queue,
                          handler_os_thread_t         * const        os_thread,
                          handler_os_critical_t       * const      os_critical
#endif // OS_SUPPORT
                          );
                          
/**
 * @brief Instantiates the handler os resource.
 * 
 * Steps:
 * 1. Check input parameters
 * 2. Check if resource is already instantiated
 * 3. Mount external interfaces
 * 4. Initialize LED instance
 * 5. Set instantiation flag
 *  
 * @param[in] self        : Pointer to the target of driver.                     
 * @return handler_state_t : Status of the function.
 * 
 * */

#ifdef SYSTEM_QUICK_BOOT
handler_state_t bsp_led_handler_inst_os_resrc_for_quick_boot (
                                              bsp_led_handler_t * const self );

handler_state_t led_control ( bsp_led_handler_t     * const              self, 
                              uint32_t                                 period,         
                              uint32_t                            blink_times,         
                              blink_proportion_t                   proportion,
                              index_led_instance_t                       idx );

handler_state_t led_register ( bsp_led_handler_t    * const           p_self, 
                               bsp_led_driver_t     * const     p_led_driver,
                               index_led_instance_t * const            index ); 
#endif // SYSTEM_QUICK_BOOT

//********************************* Declaring *******************************//

#endif /* __BSP_LED_HANDLER_H__ */
